package com.jade.zsy.purchase.facade.impl;

import com.jade.bss.DbException;
import com.jade.bss.base.RoleAction;
import com.jade.bss.base.customer.Customer;
import com.jade.bss.base.utils.CopyBean;
import com.jade.bss.db.impl.BaseFacadeImpl;
import com.jade.framework.base.context.ApplicationContextUtils;
import com.jade.framework.base.criterion.Criteria;
import com.jade.framework.base.criterion.Restrictions;
import com.jade.framework.base.util.PagingList;
import com.jade.framework.base.util.PagingResult;
import com.jade.zsy.base.common.StatusConstant;
import com.jade.zsy.base.entity.BusinessCode;
import com.jade.zsy.base.entity.Partner;
import com.jade.zsy.base.entity.Sku;
import com.jade.zsy.base.entity.Warehouse;
import com.jade.zsy.base.facade.BusinessCodeFacade;
import com.jade.zsy.base.facade.PartnerFacade;
import com.jade.zsy.base.facade.SkuFacade;
import com.jade.zsy.base.facade.WarehouseFacade;
import com.jade.zsy.finance.entity.Payable;
import com.jade.zsy.finance.entity.PayableDetail;
import com.jade.zsy.finance.service.PayableDetailFacade;
import com.jade.zsy.finance.service.PayableFacade;
import com.jade.zsy.inventory.entity.Inventory;
import com.jade.zsy.inventory.entity.InventoryLog;
import com.jade.zsy.inventory.service.InventoryFacade;
import com.jade.zsy.purchase.dao.ReceiptDao;
import com.jade.zsy.purchase.entity.Receipt;
import com.jade.zsy.purchase.entity.ReceiptDetail;
import com.jade.zsy.purchase.service.JHReceiptDetailFacade;
import com.jade.zsy.purchase.service.JHReceiptFacade;
import com.jade.zsy.purchase.vo.ReceiptDetailVo;
import com.jade.zsy.purchase.vo.ReceiptVo;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.inject.Inject;
import javax.inject.Named;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 进货单
 * User: jinya
 * Date: 2017/5/31
 * Time: 11:07
 * TEL :17701640710   MAIL:2009_jinya@163.com
 * To change this template use File | Settings | File Templates.
 */
@Service("JHReceiptFacade")
public class JHReceiptFacadeImpl extends BaseFacadeImpl implements JHReceiptFacade {
    private BusinessCodeFacade businessCodeFacade = ApplicationContextUtils.getBean("BusinessCodeFacade");
    private WarehouseFacade warehouseFacade = ApplicationContextUtils.getBean("WarehouseFacade");
    private PartnerFacade partnerFacade = ApplicationContextUtils.getBean("PartnerFacade");
    private PayableFacade payableFacade = ApplicationContextUtils.getBean("PayableFacade");
    private InventoryFacade inventoryFacade = ApplicationContextUtils.getBean("InventoryFacade");
    private SkuFacade skuFacade = ApplicationContextUtils.getBean("SkuFacade");
    private JHReceiptDetailFacade jhDetailFacade = ApplicationContextUtils.getBean("JHReceiptDetailFacade");
    @Inject
    @Named("ReceiptDao")
    private ReceiptDao entityDao;
    @Override
    @Transactional
    public void save(Object obj) throws DbException {
        Receipt entity=(Receipt)obj;
        Customer customer= (Customer) SecurityUtils.getSubject().getPrincipal();
        if(StringUtils.isEmpty(entity.getRecordNo()))//用户自定义为空系统自动生成
            entity.setRecordNo(businessCodeFacade.nextBusinessCode(BusinessCode.KEY_PUR_JH_PO));
        entity.setOwnerId(customer.getOwnerId());
        entity.setCreator(customer.getNickName());
        entity.setCreatorId(customer.getId());
        //核验 商品明细
        super.save(entity);
    }
    @Override
    @Transactional
    public void save(ReceiptVo entity) throws Exception{
        //检查是否存在明细
        if(entity.getDetailVoList()==null || entity.getDetailVoList().size()<=0){
            throw new DbException("NO_DETAIL", "明细不能为空");
        }
        Customer customer= (Customer) SecurityUtils.getSubject().getPrincipal();
        if(StringUtils.isEmpty(entity.getRecordNo()))//用户自定义为空系统自动生成
            entity.setRecordNo(businessCodeFacade.nextBusinessCode(BusinessCode.KEY_PUR_JH_PO));
        Receipt receipt = CopyBean.copy(entity, Receipt.class);
        receipt.setOwnerId(customer.getOwnerId());
        receipt.setCreator(customer.getNickName());
        receipt.setCreatorId(customer.getId());
        receipt.setStatus(StatusConstant.RECORD_WAIT_SUBMIT);
        //检查供应商状态是否正常
        if(receipt.getSupplierId()<=0)  throw new DbException("NO_DETAIL","请选择有效供应商");
        Partner partner=partnerFacade.getById(Partner.class,receipt.getSupplierId());
        if(partner==null || partner.getStatus()!= StatusConstant.RECORD_NORMAL){
            throw new DbException("NO_DETAIL","请选择有效供应商或者供应商已经停用");
        }
        receipt.setDeliverAddress(partner.getAddress());
        receipt.setDeliverMobile(partner.getTel());
        receipt.setSupplierName(partner.getName());

        //明细添加
        List<ReceiptDetail> details=new ArrayList<ReceiptDetail>();
        for(ReceiptDetailVo detailVo : entity.getDetailVoList()){
            Sku sku=skuFacade.getById(Sku.class,detailVo.getSkuId());
            if(sku==null || sku.getStatus()!= StatusConstant.RECORD_NORMAL){
                throw new DbException("NO_DETAIL", "商品不存在或者商品已下架");
            }
            //检查仓库是否可用
            if(detailVo.getWarehouseId()>0){
                Warehouse warehouse=warehouseFacade.getById(Warehouse.class,detailVo.getWarehouseId());
                if(warehouse==null || warehouse.getStatus()!= StatusConstant.RECORD_NORMAL){
                    throw new DbException("NO_DETAIL","状态异常或者不存在");
                }
            }
            ReceiptDetail detail = CopyBean.copy(detailVo, ReceiptDetail.class);
            detail.setRecordNo(receipt.getRecordNo());
            detail.setSkuCode(sku.getSkuCode());
            detail.setAmount(detail.getPrice()*detail.getQty());
            detail.setOwnerId(customer.getOwnerId());
            detail.setCreator(customer.getNickName());
            detail.setCreatorId(customer.getId());
            receipt.setTotalQty(detail.getQty()+receipt.getTotalQty());
            receipt.setTotalAmount(receipt.getTotalAmount()+detail.getAmount());
            details.add(detail);
        }
        jhDetailFacade.batchSave(details);

        receipt.setType(Receipt.JH_RECEIPT);
        super.save(receipt);
    }
    @Override
    @Transactional
    public void add(String poNo) throws Exception{

    }
    @Override
    @Transactional
    public void submit(long id) throws Exception {
        Customer customer= (Customer) SecurityUtils.getSubject().getPrincipal();
        Receipt receipt=entityDao.getById(Receipt.class,id);
        if(receipt.getStatus()!=StatusConstant.RECORD_WAIT_SUBMIT){
            throw new DbException("NO_STATUS", "不可重复提交");
        }
        receipt.setStatus(StatusConstant.RECORD_SUBMIT);
        entityDao.update(receipt);
        Criteria criteria = new Criteria();
        criteria.add(Restrictions.eq("ownerId",customer.getOwnerId()));
        criteria.add(Restrictions.eq("recordNo",receipt.getRecordNo()));
        PagingList<ReceiptDetail> receiptDetails = entityDao.queryEntity(ReceiptDetail.class, criteria);
        if(receiptDetails==null || receiptDetails.size()<=0)
            throw new DbException("EXCEPTION_RECORDE", "明细异常，不可编辑");

        //添加应付明细
        Payable payableDetail=new Payable();
        payableDetail.setPayType(PayableDetail.PAY_TYPE_PAYABLE);
        payableDetail.setRecordNo(receipt.getRecordNo());
        payableDetail.setRecordDate(receipt.getRecordDate());
        payableDetail.setAmount(receipt.getSettleAmount());
        payableDetail.setPartnerId(receipt.getSupplierId());
        payableDetail.setRemark(receipt.getPayRemark());
        payableDetail.setOwnerId(customer.getOwnerId());
        payableDetail.setCreator(customer.getNickName());
        payableDetail.setCreatorId(customer.getId());
        payableFacade.save(payableDetail);

        //添加库存记录
        List<Inventory> inventories =new ArrayList<Inventory>();
        for(ReceiptDetail detailVo : receiptDetails){
            Sku sku=skuFacade.getById(Sku.class,detailVo.getSkuId());
            Inventory inventory=new Inventory();
            inventory.setDetailId(detailVo.getId());
            inventory.setPartnerId(receipt.getSupplierId());
            inventory.setWarehouseId(detailVo.getWarehouseId());
            inventory.setWarehouseCode(detailVo.getWarehouseCode());
            inventory.setReceiptKey(detailVo.getRecordNo());
            inventory.setQty(detailVo.getQty());
            inventory.setPrice(detailVo.getPrice());
            inventory.setSkuId(detailVo.getSkuId());
            inventory.setSkuCode(sku.getSkuCode());
            inventory.setSkuSpec(sku.getSkuSpec());
            inventory.setSkuSpecId01(sku.getSkuSpecId01());
            inventory.setSkuSpecId02(sku.getSkuSpecId02());
            inventory.setSkuSpecId03(sku.getSkuSpecId03());
            inventory.setSkuSpecId04(sku.getSkuSpecId04());
            inventory.setSkuSpecId05(sku.getSkuSpecId05());
            inventory.setSkuSpecId06(sku.getSkuSpecId06());
            inventory.setSkuSpecId07(sku.getSkuSpecId07());
            inventory.setSkuSpecId08(sku.getSkuSpecId08());
            inventory.setSkuSpecId09(sku.getSkuSpecId09());
            inventory.setSkuSpecId10(sku.getSkuSpecId10());

            inventory.setUserDef01(sku.getUserDef01());
            inventory.setUserDef02(sku.getUserDef02());
            inventory.setUserDef03(sku.getUserDef03());
            inventory.setUserDef04(sku.getUserDef04());
            inventory.setUserDef05(sku.getUserDef05());
            inventory.setUserDef06(sku.getUserDef06());
            inventory.setUserDef07(sku.getUserDef07());
            inventory.setUserDef08(sku.getUserDef08());
            inventory.setUserDef09(sku.getUserDef09());
            inventory.setUserDef10(sku.getUserDef10());

            inventory.setCostPrice(detailVo.getPrice());
            inventory.setPrice(sku.getPrice());
            inventory.setOwnerId(customer.getOwnerId());
            inventory.setCreator(customer.getNickName());
            inventory.setCreatorId(customer.getId());
            inventories.add(inventory);
        }
         inventoryFacade.batchSave(inventories);
        //生成库存日志
         List<InventoryLog> inventoryLogs =new ArrayList<InventoryLog>();
         for(Inventory inventory : inventories){
             InventoryLog log=new InventoryLog();
             log.setInventoryId(inventory.getId());
             log.setRecordNo(inventory.getReceiptKey());
             log.setTitle("采购入库");
             log.setInventoryId(inventory.getId());
             log.setSkuCode(inventory.getSkuCode());
             log.setSkuName(inventory.getSkuName());
             log.setSkuSpec(inventory.getSkuSpec());
             log.setQty(inventory.getQty());
             log.setOwnerId(customer.getOwnerId());
             log.setCreator(customer.getNickName());
             log.setCreatorId(customer.getId());
         }
        inventoryFacade.batchSave(inventoryLogs);
    }
    @Override
    @Transactional
    public void cancel(long id) throws Exception {
        Customer customer= (Customer) SecurityUtils.getSubject().getPrincipal();
        Receipt receipt=entityDao.getById(Receipt.class,id);
        if(receipt.getStatus()!=StatusConstant.RECORD_SUBMIT){
            throw new DbException("NO_STATUS", "不可重复撤销");
        }
        receipt.setStatus(StatusConstant.RECORD_SUBMIT);
        entityDao.update(receipt);
        Criteria criteria = new Criteria();
        criteria.add(Restrictions.eq("ownerId",customer.getOwnerId()));
        criteria.add(Restrictions.eq("recordNo",receipt.getRecordNo()));
        PagingList<ReceiptDetail> receiptDetails = entityDao.queryEntity(ReceiptDetail.class, criteria);
        if(receiptDetails==null || receiptDetails.size()<=0)
            throw new DbException("EXCEPTION_RECORDE", "明细异常，不可编辑");

        Criteria inventoryCriteria = new Criteria();
        inventoryCriteria.add(Restrictions.eq("ownerId",customer.getOwnerId()));
        inventoryCriteria.add(Restrictions.eq("recordNo",receipt.getRecordNo()));
        PagingList<Inventory> inventories = inventoryFacade.queryEntity(Inventory.class, inventoryCriteria);
        if(inventories==null || inventories.size()<=0)
            throw new DbException("EXCEPTION_RECORDE", "库存，不可编辑");

        for(Inventory obj : inventories){
            for(ReceiptDetail detail : receiptDetails){
                if(detail.getId()==obj.getDetailId() && detail.getQty()!=obj.getQty())
                    throw new DbException("EXCEPTION_RECORDE", "数据不匹配,请走退货流程");
            }
        }
        //添加应付扣减记录
        Payable payableDetail=new Payable();
        payableDetail.setPayType(Payable.PAY_TYPE_PAYABLE);
        payableDetail.setRecordNo(receipt.getRecordNo());
        payableDetail.setRecordDate(receipt.getRecordDate());
        payableDetail.setAmount(receipt.getSettleAmount().multiply(new BigDecimal(-1)));
        payableDetail.setPartnerBankId(receipt.getSupplierId());
        payableDetail.setRemark("采购取消");
        payableDetail.setOwnerId(customer.getOwnerId());
        payableDetail.setCreator(customer.getNickName());
        payableDetail.setCreatorId(customer.getId());
        payableFacade.save(payableDetail);

        //添加库存记录
        for(Inventory inventory : inventories){
            inventory.setQty(0);
            inventory.setModifier(customer.getNickName());
            inventory.setModifyTime(new Date());
            inventoryFacade.update(inventory);
        }
        //生成库存日志
        List<InventoryLog> inventoryLogs =new ArrayList<InventoryLog>();
        for(Inventory inventory : inventories){
            InventoryLog log=new InventoryLog();
            log.setRecordNo(inventory.getReceiptKey());
            log.setInventoryId(inventory.getId());
            log.setTitle("采购撤销出库");
            log.setInventoryId(inventory.getId());
            log.setSkuCode(inventory.getSkuCode());
            log.setSkuName(inventory.getSkuName());
            log.setSkuSpec(inventory.getSkuSpec());
            log.setQty(inventory.getQty()*-1);
            log.setOwnerId(customer.getOwnerId());
            log.setCreator(customer.getNickName());
            log.setCreatorId(customer.getId());
        }
        inventoryFacade.batchSave(inventoryLogs);
    }
    @Override
    @Transactional
    public void stop(long id) throws Exception {
        Customer customer= (Customer) SecurityUtils.getSubject().getPrincipal();
        Receipt receipt=entityDao.getById(Receipt.class,id);
        if(receipt.getStatus()==StatusConstant.RECORD_NORMAL){
            receipt.setStatus(StatusConstant.RECORD_DISABLED);
        }else if(receipt.getStatus()==StatusConstant.RECORD_SUBMIT){
            Criteria criteria = new Criteria();
            criteria.add(Restrictions.eq("ownerId",customer.getOwnerId()));
            criteria.add(Restrictions.eq("recordNo",receipt.getRecordNo()));
            PagingList<ReceiptDetail> receiptDetails = entityDao.queryEntity(ReceiptDetail.class, criteria);
            if(receiptDetails==null || receiptDetails.size()<=0)
                throw new DbException("EXCEPTION_RECORDE", "明细异常，不可编辑");

            Criteria inventoryCriteria = new Criteria();
            inventoryCriteria.add(Restrictions.eq("ownerId",customer.getOwnerId()));
            inventoryCriteria.add(Restrictions.eq("recordNo",receipt.getRecordNo()));
            PagingList<Inventory> inventories = inventoryFacade.queryEntity(Inventory.class, inventoryCriteria);
            if(inventories==null || inventories.size()<=0)
                throw new DbException("EXCEPTION_RECORDE", "库存，不可编辑");

            for(Inventory obj : inventories){
                for(ReceiptDetail detail : receiptDetails){
                    if(detail.getId()==obj.getDetailId() && detail.getQty()!=obj.getQty())
                        throw new DbException("EXCEPTION_RECORDE", "数据不匹配,请走退货流程");
                }
            }
            //添加应付扣减记录
            Payable payableDetail=new Payable();
            payableDetail.setPayType(Payable.PAY_TYPE_PAYABLE);
            payableDetail.setRecordNo(receipt.getRecordNo());
            payableDetail.setRecordDate(receipt.getRecordDate());
            payableDetail.setAmount(receipt.getSettleAmount().multiply(new BigDecimal(-1)));
            payableDetail.setPartnerBankId(receipt.getSupplierId());
            payableDetail.setRemark("采购取消");
            payableDetail.setOwnerId(customer.getOwnerId());
            payableDetail.setCreator(customer.getNickName());
            payableDetail.setCreatorId(customer.getId());
            payableFacade.save(payableDetail);

            //添加库存记录
            for(Inventory inventory : inventories){
                inventory.setQty(0);
                inventory.setModifier(customer.getNickName());
                inventory.setModifyTime(new Date());
                inventoryFacade.update(inventory);
            }
            //生成库存日志
            List<InventoryLog> inventoryLogs =new ArrayList<InventoryLog>();
            for(Inventory inventory : inventories){
                InventoryLog log=new InventoryLog();
                log.setInventoryId(inventory.getId());
                log.setRecordNo(inventory.getReceiptKey());
                log.setTitle("采购撤销出库");
                log.setInventoryId(inventory.getId());
                log.setSkuCode(inventory.getSkuCode());
                log.setSkuName(inventory.getSkuName());
                log.setSkuSpec(inventory.getSkuSpec());
                log.setQty(inventory.getQty()*-1);
                log.setOwnerId(customer.getOwnerId());
                log.setCreator(customer.getNickName());
                log.setCreatorId(customer.getId());
            }
            inventoryFacade.batchSave(inventoryLogs);
        }
        receipt.setStatus(StatusConstant.RECORD_DISABLED);
        entityDao.update(receipt);
    }

    @Override
    @Transactional
    public void update(Object obj) throws DbException {
        Receipt entity=(Receipt)obj;
        Customer customer= (Customer) SecurityUtils.getSubject().getPrincipal();
        entity.setModifier(customer.getTrueName());
        super.update(entity);
    }



    @Override
    public PagingResult queryEntity(Object obj, int page, int size, String keyword, String... orders) throws DbException,IllegalAccessException, InstantiationException {
        Customer customer= (Customer) SecurityUtils.getSubject().getPrincipal();
        ReceiptVo entity=(ReceiptVo)obj;
        Criteria criteria = new Criteria((page - 1) * size, size);
        criteria.add(Restrictions.eq("ownerId",customer.getOwnerId()));
        criteria.add(Restrictions.eq("type",Receipt.JH_RECEIPT));
        if(StringUtils.isNotEmpty(keyword)){
            criteria.add(Restrictions.or(Restrictions.like("code", keyword),
                    Restrictions.like("name", keyword)));
        }

        criteria.addOrder(com.jade.framework.base.criterion.Order.desc(RoleAction.SORT_ITEM));
        PagingList pagingList = entityDao.queryEntity(Receipt.class, criteria);
        PagingResult result = PagingResult.getResult(CopyBean.copy(pagingList, ReceiptVo.class), pagingList.getTotalCount(), page, size);
        return result;
    }
}
